package com.eugenema.windowGui.controller;

import com.alibaba.excel.util.StringUtils;
import com.eugenema.util.ConfigUtil;
import com.eugenema.windowGui.MainApplication;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXSlider;
import com.jfoenix.controls.JFXTextField;
import io.datafx.controller.ViewController;
import io.datafx.controller.flow.context.FXMLViewFlowContext;
import io.datafx.controller.flow.context.ViewFlowContext;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import java.io.File;
import java.util.List;
import java.util.Optional;

/**
 * 程序设置
 * 包含配置文件的设置
 *
 * @author Eugenema
 * @date 2023/3/27 22:14
 *
 **/
@ViewController(value = "/fxml/setting.fxml", title = "程序设置")
public class SettingController {
    private static Logger logger = LoggerFactory.getLogger(SettingController.class);

    /** 视图流上下文 */
    @FXMLViewFlowContext
    private ViewFlowContext context;
    /** 主界面 */
    private Stage stage;
    /** 场景 */
    private Scene scene;
    /** 重置设置项提示框 */
    private Alert resetAlert;
    /** 消息提示框 */
    private Alert messageAlert;
    /** 设置项根标签 */
    @FXML
    private VBox settingsVBox;

    @PostConstruct
    public void init() {
        //获取主界面和场景
        stage = (Stage)context.getRegisteredObject(MainApplication.CONTEXT_KEY_STAGE);
        scene = (Scene)context.getRegisteredObject(MainApplication.CONTEXT_KEY_SCENE);

        //初始化重置设置项提示框
        resetAlert = new Alert(Alert.AlertType.CONFIRMATION);
        resetAlert.setTitle("提示");
        resetAlert.setHeaderText("是否重置所有设置项为最近一次保存的值？");
        resetAlert.setOnShowing(event -> stage.setAlwaysOnTop(false));
        resetAlert.setOnCloseRequest(event -> stage.setAlwaysOnTop(true));

        //初始化消息提示框
        messageAlert = new Alert(Alert.AlertType.INFORMATION);
        messageAlert.setTitle("通知");
        messageAlert.setHeaderText("保存成功");

        //读取设置项 ID
        configSettings(settingsVBox.getChildren(), false);
    }

    /**
     * 读取/保存配置文件
     *
     * @author 马寅广
     * @date 2023/4/27 16:23
     *
     * @param nodes 要遍历的元素列表
     * @param isSave 是否保存数据
     *
     **/
    private void configSettings(ObservableList<Node> nodes, boolean isSave) {
        for (Node child : nodes) {
            if (child instanceof VBox) {
                configSettings(((VBox)child).getChildren(), isSave);
            } else if (child instanceof HBox) {
                configSettings(((HBox)child).getChildren(), isSave);
            } else if (child instanceof JFXTextField) {
                if (isSave) {
                    //保存设置项
                    ConfigUtil.setPropertySingle(child.getId(), ((JFXTextField)child).getText());
                } else {
                    //读取设置项配置
                    String property = ConfigUtil.getProperty(child.getId());
                    ((JFXTextField)child).setText(property);
                }
            } else if (child instanceof JFXSlider) {
                if (isSave) {
                    //保存设置项
                    ConfigUtil.setPropertySingle(child.getId(), String.valueOf(((Double)((JFXSlider)child).getValue()).longValue()));
                } else {
                    //读取设置项配置
                    String property = ConfigUtil.getProperty(child.getId());
                    ((JFXSlider)child).setValue(Double.parseDouble(property));
                }
            }
        }
    }

    /**
     * 路径选择
     *
     * @author Eugenema
     * @date 2023/4/23 22:09
     *
     * @param event 事件对象
     *
     **/
    @FXML
    private void directoryChooser(ActionEvent event) {
        /** 按钮数据，规则：list(0)：文本框 ID；list(1)：是否文件选择器；list(2)：文件选择名称；list(3)：文件后缀过滤 */
        List<String> userData = (List<String>)((JFXButton)event.getSource()).getUserData();
        /** 要将路径赋值到的文本框 */
        JFXTextField textField = (JFXTextField) scene.lookup(userData.get(0));
        /** 是否文件选择器 */
        Boolean fileFlag = Boolean.valueOf(userData.get(1));
        /** 文本框内选择的路径 */
        File existFile = null;
        if (!StringUtils.isBlank(textField.getText())) {
            existFile = new File(textField.getText());
            if (existFile.isFile()) {
                existFile = existFile.getParentFile();
            } else if (!existFile.isDirectory()) {
                existFile = null;
            }
        }

        if (fileFlag) {
            /** 文件选择器 */
            FileChooser fileChooser = new FileChooser();
            if (existFile != null) {
                fileChooser.setInitialDirectory(existFile);
            }
            fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(userData.get(2), userData.get(3)));
            File file = fileChooser.showOpenDialog(stage);
            if (file != null) {
                textField.setText(file.getAbsolutePath());
            }
        } else {
            /** 路径选择器 */
            DirectoryChooser directoryChooser = new DirectoryChooser();
            if (existFile != null) {
                directoryChooser.setInitialDirectory(existFile);
            }
            File selectedDirectory = directoryChooser.showDialog(stage);
            if (selectedDirectory != null) {
                textField.setText(selectedDirectory.getAbsolutePath() + File.separator);
            }
        }
    }

    /**
     * 重置设置项
     *
     * @author Eugenema
     * @date 2023/4/27 20:34
     *
     **/
    @FXML
    private void reset() {
        Optional<ButtonType> selected = resetAlert.showAndWait();
        //点击了取消按钮或关闭
        if (!selected.isPresent() || selected.get() == ButtonType.CANCEL) {
            return;
        }

        //重置设置项
        configSettings(settingsVBox.getChildren(), false);
    }

    /**
     * 保存设置项
     *
     * @author Eugenema
     * @date 2023/4/27 20:44
     *
     **/
    @FXML
    private void saveSetting() {
        configSettings(settingsVBox.getChildren(), true);
        messageAlert.show();
    }
}
